/*!
 * \file Doll.h
 *
 * \date Jan 27, 2014
 * \author correa
 */
#ifndef DOLL_H_
#define DOLL_H_

#include <Grafo.h>
#include <VertexSet.h>

using namespace std;

class Doll
{
public:
	const Grafo&	_grafo;
	int				vidx;
	int				nodeidx;
	VertexSet*		_R;
	VertexSet*		_W;
	SingleNodeSet*	Rnode;
	SingleNodeSet*	Wnode;

	Doll(const Grafo& g, VertexSet * R);
	~Doll();
	int nextUpTo(int lastnode);
	void startUp(int v, VertexSet& subset);
};

inline Doll::Doll(const Grafo& g, VertexSet * R) : _grafo(g), vidx(0), nodeidx(0), _R(R)
{
	_W = new VertexSet(_grafo.getN());
	Rnode = new SingleNodeSet();
	Wnode = new SingleNodeSet();
}

inline Doll::~Doll()
{
	delete _R;
	delete _W;
	delete Rnode;
	delete Wnode;
}

inline int Doll::nextUpTo(int lastnode)
{
	int v;

	vidx = Rnode->least();
	while (vidx < 0 && nodeidx < lastnode) {
		_R->nodeView(++nodeidx, *Rnode);
		vidx = Rnode->least();
	}

	if (vidx < 0)
		return -1;

	v = vidx + NELEM(nodeidx);
	Rnode->remove(vidx);
	_W->nodeView(nodeidx, *Wnode);
	Wnode->add(vidx);

	return v;
}

inline void Doll::startUp(int v, VertexSet& subset)
{
	_R->copyAll(subset);
	// note that v remains in _RR only if clqOrStab=false
	_R->retainAll(_grafo.vecinos(v));
	_R->remove(v);

	nodeidx = 0;
	_R->nodeView(nodeidx, *Rnode);
	_W->removeAll();
}

#endif /* DOLL_H_ */
